import { defineStore } from 'pinia'
import axios from 'axios'
import { useGameStore } from './game'
import { COLLECTING_SKILL_MAP } from '@/stores/types'

import type { IPlayerRecipe, IPlayerchef, IPlayer, CollectingSkillType } from '@/stores/types'

/** 厨师已占用 */
interface IWorkingChef {
  id: number
  name: string
  pos: string
}

type State = {
  chefs: IPlayerchef[]
  recipes: IPlayerRecipe[]
  decoBuff: number
  workingChefs: IWorkingChef[]
}

export const usePlayerStore = defineStore('player', {
  state: (): State => ({
    chefs: [],
    recipes: [],
    decoBuff: 0,
    workingChefs: [],
  }),
  getters: {
    chefsMap: (state) => new Map(state.chefs.map((m) => [m.id, m])),
    recipesMap: (state) => new Map(state.recipes.map((m) => [m.id, m])),
    freeChefs: (state) => {
      const workingChefIds = state.workingChefs.map((m) => m.id)
      return state.chefs.filter((f) => !workingChefIds.includes(f.id))
    },
    isRecipeEx() {
      const recipesMap = this.recipesMap
      return function (recipeId: number) {
        const recipe = recipesMap.get(recipeId)
        if (recipe) {
          return recipe.ex === '是'
        }
        return false
      }
    },
  },
  actions: {
    async loadData() {
      try {
        const { data: playerData } = await axios.get<IPlayer>('./player.json')

        this.chefs = playerData.chefs.filter((f) => f.got === '是')
        this.recipes = playerData.recipes.filter((f) => f.got === '是')
        // 装饰加成
        this.decoBuff = playerData.decorationEffect / 100
      } catch (e) {
        console.error(e)
      }
    },
    /**
     * 获取厨师装备对采集技能的加成
     * @param chefId 厨师id
     * @returns 返回新的收集技能值
     */
    getChefCollectingSkills(chefId: number) {
      const { equipsMap, skillsMap, chefsMap } = useGameStore()
      const chefSkills = { veg: 0, fish: 0, creation: 0, meat: 0 }

      const chef = this.chefsMap.get(chefId)
      const chefInfo = chefsMap.get(chefId)
      if (!(chef && chefInfo)) return null
      getObjectKeys(chefSkills).forEach((key) => (chefSkills[key] = chefInfo[key]))

      const chefEquip = equipsMap.get(chef.equip)
      if (chefEquip) {
        chefEquip.skill.forEach((skillId) => {
          const skillData = skillsMap.get(skillId)
          if (!skillData) return
          skillData.effect.forEach(({ condition, cal, type, value }) => {
            if (condition === 'Self' && cal === 'Abs' && isCollectingSkill(type)) {
              chefSkills[COLLECTING_SKILL_MAP[type]] += value
            }
          })
        })
      }

      return chefSkills
    },
    /** 添加厨师占用 */
    setWorkingChef(item: IWorkingChef) {
      if (!this.workingChefs.find((f) => f.id === item.id)) {
        this.workingChefs.push(item)
      }
    },
    /** 移除厨师占用 */
    removeWorkingChef(chefId: number) {
      const index = this.workingChefs.findIndex((f) => f.id === chefId)
      if (index > -1) {
        this.workingChefs.splice(index, 1)
      }
    },
  },
  persist: {
    key: 'usePlayerStore',
    pick: ['workingChefs'],
  },
})

function getObjectKeys<T extends object>(obj: T): Array<keyof T> {
  return Object.keys(obj) as Array<keyof T>
}

function isCollectingSkill(value: string): value is CollectingSkillType {
  return Object.keys(COLLECTING_SKILL_MAP).includes(value)
}
